package com.custom.controlmoveview;

import android.content.Context;
import android.content.res.TypedArray;
import android.graphics.Canvas;
import android.graphics.Color;
import android.graphics.Paint;
import android.graphics.Rect;
import android.graphics.RectF;
import android.os.Handler;
import android.util.AttributeSet;
import android.util.Log;
import android.view.MotionEvent;
import android.view.View;

import androidx.annotation.Nullable;

import java.util.Calendar;


/**
 * @description：TODO
 * @Author MRyan
 * @Date 2020/3/1 16:49
 * @Version 1.0
 */
public class CustomMoveClockView extends View {
    private int mClockViewSize;//画布大小
    private int mClockSize;//控件大小
    private int mClockColor;//时钟外框颜色
    private int mCustomPanColor;//刻度线颜色
    private int mClockWidth;//时钟外框宽度
    private Paint mClockPaint;//绘制整体轮廓画笔
    private Paint mirclePanPaint;//绘制刻度线
    private Paint mircleCirPaint;//绘制表芯
    private Paint mirclePanTextPaint;//时钟文字画笔
    private int mCustomPanTextColor;//时钟文字颜色
    private int mCustomPanTextSize;//时钟文字大小
    private Paint mClockHourPaint;//绘制时钟
    private Paint mClockMinutePaint;//绘制分钟
    private Paint mClockSecondPaint;//绘制秒钟
    private Calendar mCalendar; //获取时间
    private int mRadius;
    private RectF mClockRect;//时钟轮廓位置
    private static final int istrue = 521;
    private int startY;
    private int startX;

    public CustomMoveClockView(Context context) {
        super(context);
    }

    public CustomMoveClockView(Context context, @Nullable AttributeSet attrs) {
        super(context, attrs);
        initAttrs(context, attrs);//自定义属性
        initPaint();
        //发送消息，监测秒针
        mhandler.sendEmptyMessage(istrue);
    }

    public CustomMoveClockView(Context context, @Nullable AttributeSet attrs, int defStyleAttr) {
        super(context, attrs, 0);
    }

    @Override
    protected void onMeasure(int widthMeasureSpec, int heightMeasureSpec) {
        setMeasuredDimension(mClockViewSize, mClockViewSize);
    }

    @Override
    protected void onDraw(Canvas canvas) {
        super.onDraw(canvas);
        //绘制刻度线 和 数字
        drwaGraduationLine(canvas);
        //绘制表针
        drawClockLine(canvas);
    }

    /***
     * 绘制表针
     * @param canvas
     */
    private void drawClockLine(Canvas canvas) {
        //获取系统当时的时间
        int hour = mCalendar.get(Calendar.HOUR);
        int minute = mCalendar.get(Calendar.MINUTE);
        int second = mCalendar.get(Calendar.SECOND);
        if (hour > 12) {//12小时质
            hour = hour - 12;
        }
        float hourDregrees = (hour / 12f * 360) + (minute / 60f * 30) + 180;  //时针旋转的角度
        float minuDegrees = (minute / 60f * 360) + 180;  //分针旋转的角度
        float sencondDegree = (second / 60f * 360) + 180;   //秒针旋转的角度
        Log.e("MessageDreGrees", hourDregrees + "  " + minuDegrees + "  " + sencondDegree);
        Log.e("MessageDreGree", hour + "  " + minute + "  " + second);

        canvas.rotate(hourDregrees, mClockSize / 2, mClockSize / 2);
        canvas.drawLine(mClockSize / 2, mClockSize / 2 - 50, mClockSize / 2, mClockSize / 2 + 180, mClockHourPaint); //画时间刻度线
        canvas.restore();  //合并画布


        //绘制分针
        canvas.save();
        canvas.rotate(minuDegrees, mClockSize / 2, mClockSize / 2);  //旋转画布
        canvas.drawLine(mClockSize / 2, mClockSize / 2 - 50, mClockSize / 2, mClockSize / 2 + 230, mClockMinutePaint); //画时间刻度线;
        canvas.restore(); //合并画布


        //绘制秒针
        canvas.save();
        canvas.rotate(sencondDegree, mClockSize / 2, mClockSize / 2); //旋转画布
        canvas.drawLine(mClockSize / 2, mClockSize / 2 - 50, mClockSize / 2, mClockSize / 2 + 300, mClockSecondPaint); //画时间刻度线;
        canvas.restore(); //合并画布

        canvas.save();
        //绘制表芯
        canvas.drawCircle(mClockSize / 2, mClockSize / 2, 15, mircleCirPaint);
        canvas.restore();
    }

    /***
     * 绘制刻度线 和 数字
     * @param canvas
     */
    private void drwaGraduationLine(Canvas canvas) {
        //绘制 外轮廓的圆弧
        canvas.drawArc(mClockRect, 0, 360, false, mClockPaint);
        //绘制 刻度线和数字  （一圈360度 90度 180度 270度 360度为粗长 特定刻度 其余为小刻度）
        for (int i = 0; i < 60; i++) {
            if (i == 0 || i == 15 || i == 30 || i == 45) {
                //画刻度线
                mirclePanPaint.setStrokeWidth(15);
                mirclePanPaint.setColor(Color.parseColor("#FA838383"));
                canvas.drawLine(mClockSize / 2, mClockWidth + 5, mClockSize / 2, mClockWidth + 50, mirclePanPaint);
                //设置时间数字
                String degree = String.valueOf(i / 5);
                if (i == 0) {
                    degree = "12";
                }
                //获取数字绘制位置
                Rect rect = new Rect();
                mirclePanTextPaint.getTextBounds(degree, 0, degree.length(), rect);
                mirclePanTextPaint.setTextSize(mCustomPanTextSize);
                mirclePanTextPaint.setStrokeWidth(8);
                mirclePanTextPaint.setFakeBoldText(true);//设置数字粗体
                int dx = mClockSize / 2 - rect.width() / 2 - 18;
                //绘制时间数字
                canvas.drawText(degree, dx, mClockWidth + 120, mirclePanTextPaint);
            } else if (i % 5 == 0) {
                mirclePanPaint.setStrokeWidth(15);
                mirclePanPaint.setColor(mClockColor);
                canvas.drawLine(mClockSize / 2, mClockWidth + 5, mClockSize / 2, mClockWidth + 40, mirclePanPaint);
                //设置时间数字
                String degree = String.valueOf(i / 5);
                //获取文字绘制位置
                Rect rect = new Rect();
                mirclePanTextPaint.getTextBounds(degree, 0, degree.length(), rect);
                mirclePanTextPaint.setTextSize((float) (mCustomPanTextSize * 0.6));
                mirclePanTextPaint.setStrokeWidth(8);
                int dx = mClockSize / 2 - rect.width() / 2;
                //绘制时间数字
                canvas.drawText(degree, dx, mClockWidth + 100, mirclePanTextPaint);
            } else {
                mirclePanPaint.setStrokeWidth(5);
                mirclePanPaint.setColor(mClockColor);
                canvas.drawLine(mClockSize / 2, mClockWidth + 5, mClockSize / 2, mClockWidth + 30, mirclePanPaint);
            }
            canvas.rotate(6, mClockSize / 2, mClockSize / 2);
        }
        //保存表盘和刻度的画布
        canvas.save();
    }

    /**
     * 获取自定义属性
     *
     * @param context
     * @param attrs
     */
    private void initAttrs(Context context, AttributeSet attrs) {
        TypedArray typedArray = context.obtainStyledAttributes(attrs, R.styleable.CustomMoveClockView);
        mClockColor = typedArray.getColor(R.styleable.CustomMoveClockView_customClockColor, mClockColor);
        mCustomPanColor = typedArray.getColor(R.styleable.CustomMoveClockView_customPanColor, mCustomPanColor);
        mCustomPanTextColor = typedArray.getColor(R.styleable.CustomMoveClockView_customPanTextColor, mCustomPanTextColor);
        mCustomPanTextSize = (int) typedArray.getDimension(R.styleable.CustomMoveClockView_customPanTextSize, dpx2(33));
        mClockViewSize = (int) typedArray.getDimension(R.styleable.CustomMoveClockView_customClockSize, dpx2(300));
        mClockWidth = (int) typedArray.getDimension(R.styleable.CustomMoveClockView_customClockborderWidth, dpx2(8));
        typedArray.recycle();
        mClockSize = mClockViewSize;//容错
        mRadius = mClockSize / 2;
        mCalendar = Calendar.getInstance();
    }

    //消息队列机制
    private Handler mhandler = new Handler() {
        public void handleMessage(android.os.Message msg) {
            switch (msg.what) {
                case istrue:
                    //重新获取时间
                    mCalendar = Calendar.getInstance();
                    //重新绘制界面
                    invalidate();//告诉UI主线程重新绘制
                    //再次发送消息，递归调用，再次监测秒针
                    mhandler.sendEmptyMessageDelayed(istrue, 1000);
                    break;

                default:
                    break;
            }
        }

        ;

    };


    /**
     * 初始化画笔
     */
    private void initPaint() {
        mClockPaint = new Paint();
        mClockPaint.setColor(mClockColor);
        mClockPaint.setAntiAlias(true);
        mClockPaint.setStrokeWidth(mClockWidth);
        mClockPaint.setStyle(Paint.Style.STROKE);

        mircleCirPaint = new Paint();
        mircleCirPaint.setColor(mClockColor);
        mircleCirPaint.setAntiAlias(true);
        mircleCirPaint.setStyle(Paint.Style.FILL);
        mircleCirPaint.setStrokeWidth(5);

        mirclePanPaint = new Paint();
        mirclePanPaint.setColor(mCustomPanColor);
        mirclePanPaint.setAntiAlias(true);
        mirclePanPaint.setStyle(Paint.Style.FILL);

        mirclePanTextPaint = new Paint();
        mirclePanTextPaint.setColor(mCustomPanTextColor);
        mirclePanTextPaint.setStyle(Paint.Style.FILL);

        mClockHourPaint = new Paint();
        mClockHourPaint.setColor(Color.parseColor("#FA838383"));
        mClockHourPaint.setStyle(Paint.Style.FILL);
        mClockHourPaint.setStrokeWidth(25);

        mClockMinutePaint = new Paint();
        mClockMinutePaint.setColor(Color.parseColor("#FA838383"));
        mClockMinutePaint.setStyle(Paint.Style.FILL);
        mClockMinutePaint.setStrokeWidth(17);

        mClockSecondPaint = new Paint();
        mClockSecondPaint.setColor(mCustomPanColor);
        mClockSecondPaint.setStyle(Paint.Style.FILL);
        mClockSecondPaint.setStrokeWidth(10);


        mClockRect = new RectF(mClockWidth, mClockWidth, mClockSize - mClockWidth, mClockSize - mClockWidth);
    }

    //重写滑动事件
    @Override
    public boolean onTouchEvent(MotionEvent event) {
        switch (event.getAction()) {
            case MotionEvent.ACTION_DOWN:
                Log.e("打印操作：", "按下了");
                //获取当前按下的坐标
                startX = (int) event.getRawX();
                startY = (int) event.getRawY();
                break;
            case MotionEvent.ACTION_MOVE:
                //获取移动后的坐标
                if (onMoveListener != null) {
                    onMoveListener.onMove(true);//接口回调 移动中
                }
                int moveX = (int) event.getRawX();
                int moveY = (int) event.getRawY();
                //拿到手指移动距离的大小
                int move_bigX = moveX - startX;
                int move_bigY = moveY - startY;
                Log.e("打印操作：", "\nX移动了" + move_bigX + "\nY移动了" + move_bigY);
                //拿到当前控件未移动的坐标
                int left = getLeft();
                int top = getTop();
                left += move_bigX;
                top += move_bigY;
                int right = left + getWidth();
                int bottom = top + getHeight();
                layout(left, top, right, bottom);
                startX = moveX;
                startY = moveY;
                break;
            case MotionEvent.ACTION_UP:
                Log.e("打印操作：", "抬起了");
                if (onMoveListener != null) {
                    onMoveListener.onMove(false);//接口回调 未移动
                }
                break;
        }
        return true;//此处一定要返回true，否则监听不生效
    }

    /***
     * 定义接口 暴露接口
     */
    private OnMoveListener onMoveListener;

    public interface OnMoveListener {
        void onMove(boolean isMove);
    }

    public void setOnMoveListener(OnMoveListener onMoveListener) {
        this.onMoveListener = onMoveListener;
    }

    public int dpx2(int Value) {
        final float scale = getResources().getDisplayMetrics().density;
        return (int) (Value * scale + 0.5f);
    }

}
